// ## 2023/10/30 # 黑店小小二 # 群友脑洞特技第一期,增加「客逆」，「安抚」，「护驾」 ##

namespace 群友新特技 {
	class Main {
    pk::random random(pk::rand());

    pk::func163_t@ prev_callback_163;
    pk::func209_t@ prev_callback_209;

    Main()
    {
    	@prev_callback_163 = cast<pk::func163_t@>(pk::get_func(163));
      pk::reset_func(163);
      pk::set_func(163, pk::func163_t(func163));

      @prev_callback_209 = cast<pk::func209_t@>(pk::get_func(209));
      pk::reset_func(209);
      pk::set_func(209, pk::func209_t(func209));

      pk::bind(111, pk::trigger111_t(onForceBegin));
      pk::bind(174, pk::trigger174_t(onUnitDone));
      pk::bind(175, pk::trigger175_t(onUnitDestroy));
    }

    void func163(pk::unit_attr& attr, const pk::detail::arrayptr<pk::person@>& in member, int weapon_id, uint troops, int type, int status, bool navy, bool shoubyou)
    {
      prev_callback_163(attr, member, weapon_id, troops, type, status, navy, shoubyou);
      pk::person@ leader = member[0];
      if (!pk::is_alive(leader)) return;
      pk::unit@ unit = pk::get_unit(pk::get_unit_id(leader));
      if (unit is null) return ;
      if (ch::has_skill(unit, 特技_客逆))
      {
        pk::building@ building = pk::get_building(pk::get_building_id(unit.pos));
        if (building !is null)
        {
          int buff = building.get_force_id() != unit.get_force_id() ? pk::core::skill_constant_value(特技_客逆) : (-1 * pk::core::skill_constant_value(特技_客逆, 1));
          attr.stat[部队能力_攻击] = int(pk::min(255.f, float(attr.stat[部队能力_攻击] * (buff + 100) / 100)));
          attr.stat[部队能力_防御] = int(pk::min(255.f, float(attr.stat[部队能力_防御] * (buff + 100) / 100)));
        }
      }
    }

    void func209(pk::damage_info& info, pk::unit@ attacker, int tactics_id, const pk::point& in target_pos, int type, int critical, bool ambush, int rettype)
    {
      prev_callback_209(info, attacker, tactics_id, target_pos, type, critical, ambush, rettype);
      pk::unit@ target_unit = pk::get_unit(target_pos);
      if (target_unit !is null and type == 0 and rettype != 15)
      {
        array<pk::point> rings = pk::range(target_unit.get_pos(), 1, 1);
        for (int i = 0; i < int(rings.length); i++)
        {
          pk::unit@ dst = pk::get_unit(rings[i]);
          if (dst !is null and pk::is_alive(dst) and dst.get_force_id() == target_unit.get_force_id() and ch::has_skill(dst, 特技_护驾))
          {
            pk::person@ dst_leader = pk::get_person(dst.leader);
            pk::person@ target_leader = pk::get_person(target_unit.leader);
            if (dst_leader.rank > target_leader.rank) continue;
            int infact_damage = pk::min(dst.troops, int(info.troops_damage * pk::core::skill_constant_value(特技_护驾) / 100.f));
            info.troops_damage = int(info.troops_damage - infact_damage);
            if (pk::is_in_screen(target_unit.pos))
            {
              pk::say(pk::encode(pk::format("{}大人别怕，有我在", pk::get_name(target_leader))), dst_leader, dst);
            }
            ch::add_troops(dst, -infact_damage, true);
            if (dst is null or dst.troops == 0)
            {
              pk::create_death_effect(dst, attacker);
              pk::kill(dst, attacker);
            }
            break;
          }
        }
        
      }
    }

    void onForceBegin(pk::force@ force)
    {
      if (!pk::is_alive(force) or force.get_id() >= 非贼势力_末) return ;
      func_势力城池(force);
      fun_全部队(force);
    }

    void onUnitDone(pk::unit@ unit, int type)
    {
      if (ch::has_skill(unit, 特技_符道))
      {
        auto unit_p = ch::get_unit_p(unit.get_id());
        if (int(unit_p.wounded) > 0 and pk::rand_bool(pk::core::skill_constant_value(特技_符道)))
        {
          int wounded = ch::add_troops(unit, int(unit_p.wounded / 2), true);
          unit_p.wounded = unit_p.wounded - wounded;
          pk::say(pk::encode('得授符法，驱鬼灭害'), pk::get_person(ch::who_has_skill(unit, 特技_符道)), unit);
        }
      }
    }

    void onUnitDestroy(pk::unit@ attacker, pk::unit@ target)
    {
      func_复归(target);
    }

    void func_势力城池(pk::force@ force)
    {
      for (int i = 0; i < 据点_末; i += 1)
      {
        pk::building@ building = pk::get_building(i);
        if (building.get_force_id() == force.get_id())
        {
          if (ch::has_skill(building, 特技_安抚))
          {
            pk::person@ person = pk::get_person(ch::who_has_skill(building, 特技_安抚));
            ch::add_population(i, person.stat[武将能力_魅力] * pk::core::skill_constant_value(特技_安抚), true);
          }
          if (ch::has_skill(building, 特技_纳贤))
          {
            pk::list<pk::person@> person_list = pk::get_person_list(building, pk::mibun_flags(身份_在野, 身份_俘虏));
            int person_count = int(person_list.count);
            if (person_count > 0)
            {
              for (int p = 0; p < person_count; p += 1)
              {
                pk::person@ person = person_list[p];
                if (person.ban_timer > 0)
                {
                  person.ban_timer = person.ban_timer - 1;
                  if (person.ban_timer == 0) person.banned_kunshu = -1;
                }
              }
            }
          }
        }
      }
    }

    void fun_全部队(pk::force@ force)
    {
      pk::list<pk::unit@> unit_list = pk::get_unit_list(force);
      if (unit_list.count == 0) return ;
      for (int i = 0; i < int(unit_list.count); i += 1)
      {
        pk::unit@ unit = unit_list[i];
        if (!pk::is_alive(unit)) continue;

        bool 幻术 = ch::has_skill(unit, 特技_幻术) and pk::rand_bool(pk::core::skill_constant_value(特技_幻术));
        bool 毁粮 = ch::has_skill(unit, 特技_毁粮);

        if (!幻术 and !毁粮) continue;

        int stat = unit.attr.stat[部队能力_智力];
        int 幻术_effect_unit = 0;
        int 毁粮_effect_unit = 0;
        array<pk::point> rings = pk::range(unit.get_pos(), 1, 2);

        for (int a = 0; a < int(rings.length); a += 1)
        {
          pk::unit@ dst = pk::get_unit(rings[a]);
          if (dst !is null and pk::is_alive(dst))
          {
            if (幻术) 幻术_effect_unit += 幻术_处理(unit, dst, stat);
            if (毁粮) 毁粮_effect_unit += 毁粮_处理(unit, dst);
          }
        }

        if (幻术 and 幻术_effect_unit > 0)
        {
          pk::say(pk::encode('仙家幻术，凡人难明!'), pk::get_person(ch::who_has_skill(unit, 特技_幻术)), unit);
        }

        if (毁粮 and 毁粮_effect_unit > 0)
        {
          pk::say(pk::encode('断敌粮秣，此战可胜!'), pk::get_person(ch::who_has_skill(unit, 特技_毁粮)), unit);
        }

      }
    }

    void func_复归(pk::unit@ target)
    {
      array<pk::point> rings = pk::range(target.get_pos(), 1, 2);
      int count = 0;
      for (int i = 0; i < int(rings.length); i++)
      {
        pk::unit@ dst = pk::get_unit(rings[i]);
        if (dst !is null and pk::is_alive(dst) and dst.get_force_id() == target.get_force_id() and ch::has_skill(dst, 特技_复归))
        {
          pk::add_troops(dst, random(200, 300), true);
          pk::say(pk::encode('使宣号令，令其归之'), pk::get_person(ch::who_has_skill(dst, 特技_复归)), dst);
        }
      }
    }

    int 幻术_处理(pk::unit@ attacker, pk::unit@ target, int stat)
    {
      if (target.get_force_id() != attacker.get_force_id() and int(target.attr.stat[部队能力_智力]) < stat)
      {
        pk::add_energy(target, -pk::core::skill_constant_value(特技_幻术, 1), true);
        return 1;
      }
      return 0;
    }

    int 毁粮_处理(pk::unit@ attacker, pk::unit@ target)
    {
      if (target.get_force_id() != attacker.get_force_id())
      {
        pk::add_food(target, -ch::randint(50, 200), true);
        return 1;
      }
      return 0;
    }


	}
	Main main;
}